﻿namespace LS.Nc6.Web.Entry.Areas.Systems.Controllers
{
    [Route("[area]/[controller]/[action]")]
    [Area("Systems")]
    [ApiDescriptionSettings("Default")]
    public class UserController : BaseAdminController
    {
        #region UserController

        private readonly ISysUserService _userService;
        private readonly ISysOrganizeService _organizeService;
        private readonly ISysRoleService _roleService;
        private readonly ISysDictionaryService _dictionaryService;
        private readonly ISysNoticeService _noticeService;
        private readonly ISysConfigurationService _configurationService;
        private readonly ICache _cache;
        public UserController(ISysUserService userService, ISysOrganizeService organizeService, ISysRoleService roleService, ISysDictionaryService dictionaryService, ISysNoticeService noticeService,
            ISysConfigurationService configurationService,
            IOptions<CacheOptions> cacheOptions, Func<string, ISingleton, object> resolveNamed)
            : base(cacheOptions, resolveNamed)
        {
            _userService = userService;
            _organizeService = organizeService;
            _roleService = roleService;
            _dictionaryService = dictionaryService;
            _noticeService = noticeService;
            _cache = resolveNamed(cacheOptions.Value.CacheType.ToString(), default) as ICache;
            _configurationService  = configurationService;
        }
        #endregion

        #region 页面

        public ActionResult Index()
        {
            SysPower(SysMenuConstant.MENU_SYS_USER, SysMenuConstant.FUN_SELECT, UserInfo.ID.ToString());
            return View();
        }

        public async   Task<ActionResult> CreateUser()
        {
            SysPower(SysMenuConstant.MENU_SYS_USER, SysMenuConstant.FUN_ADD, UserInfo.ID.ToString());
            var model = new SysUserEntity();
            model.Isenable = true;
            
            ViewBag.Photo = "/images/user.png";
            var rolelist = await _roleService.List(a=>true, a => new { a.RoleSeq });
            ViewBag.RoleList = rolelist;
            model.Id = 0;
           
            List<Hashtable> hsUserRole = new List<Hashtable>();
            foreach (var item in rolelist)
            {
                Hashtable hs = new Hashtable();
                hs.Add("RoleCode", item.RoleCode);
                hs.Add("RoleName", item.RoleName);
                hs.Add("Checked",  "0");
                hsUserRole.Add(hs);
            }
            ViewBag.RoleList = hsUserRole;
           
            ViewBag.UserTypeList = await _dictionaryService.DictionaryTagByDicType(SysDictionaryType.ENUM_USERTYPE);
            //ViewBag.OrganizeList = await _organizeService.List(a=>true,a=>a.OrgSeq);
            return View("EditUser", model);
        }
        public async Task<ActionResult> EditUser(int id)
        {
            SysPower(SysMenuConstant.MENU_SYS_USER, SysMenuConstant.FUN_UPDATE, UserInfo.ID.ToString());
            var model =  await _userService.GetByIdAsync(id);
            if (model == null)
            {
                return ErrorCustomMsg(ResponseHelper.NONEXISTENT);
            }
            var roleuser = await _userService.GetRoleUser(model.Id);
            List<string> userroleList = new List<string>();
            if (roleuser != null && roleuser.Count > 0)
            {
                StringBuilder sbrole = new StringBuilder();
                foreach (var item in roleuser)
                {
                    sbrole.Append(item.RoleCode + ",");
                    userroleList.Add(item.RoleCode);
                }
                model.RoleCode = RequestHelper.RemoveSuffixChar(sbrole.ToString());
            }
            
            model.UserPwd = "";
            var  rolelist =await _roleService.List(a => true, a => a.RoleSeq);
            List<Hashtable> hsUserRole = new List<Hashtable>();
            foreach (var item in rolelist)
            {
                Hashtable hs = new Hashtable();
                hs.Add("RoleCode", item.RoleCode);
                hs.Add("RoleName", item.RoleName);
                hs.Add("Checked", userroleList.Contains(item.RoleCode)?"1":"0");
                hsUserRole.Add(hs);
            }
            ViewBag.RoleList = hsUserRole;
            if (!model.Isenable.HasValue)
            {
                model.Isenable = false;
            }
            //if (model.CompanyId.HasValue)
            //{
            //    model.CompanyName = ICmsCompanyService.GetById(model.CompanyId.Value)?.CompanyName;
            //}
            //ViewBag.OrganizeList = await _organizeService.List(a => true, a => a.OrgSeq);
            ViewBag.UserTypeList = await _dictionaryService.DictionaryTagByDicType(SysDictionaryType.ENUM_USERTYPE);
            return View(model);
        }

        public  async Task<ActionResult> Detail()
        {
            var model = await _userService.GetByIdAsync(UserInfo.ID);
            if (model == null)
            {
                return ErrorCustomMsg(ResponseHelper.NONEXISTENT);
            }
            var roleuser = await _userService.GetRoleUser(model.Id);
            var rolelist = await _roleService.List(a => true, a => a.RoleSeq);
            StringBuilder sbrole = new StringBuilder();
            if (roleuser != null && roleuser.Count > 0)
            {
                foreach (var item in roleuser)
                {
                   var rolemodel= rolelist.Where(w => w.RoleCode == item.RoleCode).FirstOrDefault();
                    if (rolemodel != null)
                    {
                        sbrole.Append(rolemodel.RoleName+",");
                    }
                }
            }
            ViewBag.RoleNames = RequestHelper.RemoveSuffixChar(sbrole.ToString());

            model.UserPwd = "";
            ViewBag.UserType =await _dictionaryService.DictionaryName(model.UserType.ToString(),SysDictionaryType.ENUM_USERTYPE);


            //ViewBag.UserMessageList = GetUserMseeage(0);
            return View(model);
        }

        public ActionResult ModifyPwd()
        {
            return View();
        }

        public ActionResult UploadPicture()
        {
            return View();
        }

        public async  Task<ActionResult> AuditUser()
        {
            SysPower(SysMenuConstant.MENU_SYS_USER, SysMenuConstant.FUN_AUDIT, UserInfo.ID.ToString());
            var rolelist = await _roleService.List(a => true, a => a.RoleSeq);
            List<Hashtable> hsUserRole = new List<Hashtable>();
            foreach (var item in rolelist)
            {
                Hashtable hs = new Hashtable();
                hs.Add("RoleCode", item.RoleCode);
                hs.Add("RoleName", item.RoleName);
                hsUserRole.Add(hs);
            }
            ViewBag.RoleList = hsUserRole;
            var  ids = Request.Query["ids"].ToString().GetStringToLongArryNoNull();  
            ViewBag.Ids = ids;
            ViewBag.UserList = _userService.List(a=>ids.Contains(a.Id),null);
            return View();

        }


        #endregion


        #region  公共方法
        [HttpGet]
        public async Task<ResponseResultDataList> GetAllUser()
        {
            string username = RequestHelper.FilterParam(Request.Query["username"]);
            string realrname = RequestHelper.FilterParam(Request.Query["realrname"]);
            string email = RequestHelper.FilterParam(Request.Query["email"]);
            var orgid = Request.Query["orgid"].ToString().GetQueryValueOrNull<int>(0);

            string userstatus = RequestHelper.FilterParam(Request.Query["userstatus"]);

            var page = Request.Query["page"].ToString().GetQueryValueOrNull<int>(1);
            var limit = Request.Query["limit"].ToString().GetQueryValueOrNull<int>(20);
            string field = Request.Query["field"];
            string order = Request.Query["order"];

            var expable = Expressionable.Create<SysUserEntity>();
            expable.AndIF(!string.IsNullOrEmpty(realrname), a => a.RealName. Contains(realrname));
            expable.AndIF(!string.IsNullOrEmpty(username), a => a.UserName.Contains(username));
            expable.AndIF(!string.IsNullOrEmpty(email), a => a.Email.Contains(email));
            expable.AndIF(!string.IsNullOrEmpty(userstatus), a => a.UserStatus==userstatus.ParseToInt());
            var exp = expable.ToExpression();

          
            var strField = RequestHelper.FilterParam(field);
            var strOrder = RequestHelper.FilterParam(order);

            Expression<Func<SysUserEntity, object>> expressionOrder;
            if (string.IsNullOrEmpty(strField) || string.IsNullOrEmpty(strOrder))
            {
                expressionOrder = (a) => new { a.Id };
            }
            else
            {
                //实现字段排序
                expressionOrder = (a) => new { a.CreateDate };
            }
            var result = await _userService.PageList(exp, page, limit, expressionOrder);
            var  dicResult =await _dictionaryService.DictionaryTagByDicType(SysDictionaryType.ENUM_USERTYPE);
            var  orgResult= await _organizeService.List(a => true, a => a.Id);
            foreach (var item in result.Items)
            {
                item.UserTypeName = dicResult.Where(w => w.Dvalue == item.UserType.ToString())?.FirstOrDefault()?.Dname;
                item.CompanyName = orgResult.Where(w => w.Id == item.CompanyId)?.FirstOrDefault()?.OrgName;
            }
            return new ResponseResultDataList { code = ResponseHelper.SEUCCESSCODE, message = "请求成功", data = result.Items, count = result.TotalCount };
        }

        /// <summary>
        /// 保存用户
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [OpLog]
        public async Task<ResponseResult> SaveUser([FromBody]SysUserEntity model)
        {

            if (string.Equals("admin", model.UserName, StringComparison.InvariantCultureIgnoreCase))
            {
                return ResponseHelper.MessageResult(ResponseHelper.OPERATE_YHMYBZY);
            }
            var expable = Expressionable.Create<SysUserEntity>();

            expable.And(a => a.UserName == model.UserName);
            

            SysUserEntity editmodel = null;
            bool power = true;
            if (model.Id > 0)
            {
                power = SysPower(SysMenuConstant.MENU_SYS_USER, SysMenuConstant.FUN_UPDATE, UserInfo.ID.ToString(), false);
                if (!power)
                {
                    return ResponseHelper.MessageResult(ResponseHelper.PERMISSION_QXZU);
                }
                editmodel = await _userService.GetByIdAsync(model.Id);

                expable.And(a => a.Id != model.Id);
            }
            else
            {
                power = SysPower(SysMenuConstant.MENU_SYS_USER, SysMenuConstant.FUN_ADD, UserInfo.ID.ToString(), false);
                if (!power)
                {
                    return ResponseHelper.MessageResult(ResponseHelper.PERMISSION_QXZU);
                }
            }
            var exp = expable.ToExpression();
            var userlist = await _userService.List(exp, a => a.Id);
            if (userlist.Count > 0)
            {
                return ResponseHelper.MessageResult(ResponseHelper.OPERATE_YHMYBZY);
            }
            
            #region 角色
            var listrole = CommonUtil.GetStringListNoNull(model.RoleCode);
            List<SysUserRoleEntity> lsrole = new List<SysUserRoleEntity>();
            if (listrole.Count > 0)
            {
                foreach (var item in listrole)
                {
                    lsrole.Add(new SysUserRoleEntity { RoleCode = item, UserId = model.Id });
                }
            }
            #endregion

            #region 组织机构
            //var listorg = RequestHelper.GetStringListNoNull("userorgs");
            List<SysOrganizeUserEntity> lsorg = new List<SysOrganizeUserEntity>();
            //if (listorg.Count > 0)
            //{
            //    foreach (var item in listorg)
            //    {
            //        lsorg.Add(new SysOrganizeUserEntity { Orgcode = item, UserId = model.Id.ToString() });
            //    }
            //}
            #endregion
            int result = 0;

            if (model.Id > 0)
            {
                if (!string.IsNullOrEmpty(model.UserPwd))
                {
                    var md5pwd = MD5Encryption.Encrypt(model.UserPwd);
                    model.UserPwd = md5pwd;
                }
                else
                {
                    model.UserPwd = editmodel.UserPwd;
                }
                CommonMethodHelper.MapperToModel(editmodel, model, null);
                result = await _userService.UpdateUser(editmodel, lsrole, lsorg );
            }
            else
            {
                model.UserPwd = MD5Encryption.Encrypt(model.UserPwd);
               
                model.UserStatus = 1;//如果后台添加无需审核
                result = await _userService.InsertUser(model, lsrole, lsorg);

            }
           return  ResponseHelper.SaveResult(result);
            
        }

        /// <summary>
        /// 保存用户
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [OpLog]
        public async Task<ResponseResult> SaveMyUser([FromBody]SysUserEntity model)
        {
            if (model.Id!=UserInfo.ID)
            {
                return ResponseHelper.MessageResult(ResponseHelper.PERMISSION_FFCZ);
            }
            SysUserEntity  editmodel = await _userService.GetByIdAsync(model.Id);

            editmodel.RealName = model.RealName;
            editmodel.Mobile = model.Mobile;
            editmodel.Email = model.Email;

            int result = await _userService.UpdateAsync(editmodel);
            return ResponseHelper.SaveResult(result);
        }

        [HttpPost]
        [OpLog]
        public async Task<ResponseResult> DelUser([FromBody]DeletDataInput input)
        {
            var r = SysPower(SysMenuConstant.MENU_SYS_USER, SysMenuConstant.FUN_DELETE, UserInfo.ID.ToString(), false);
            if (!r)
            {
                return ResponseHelper.MessageResult(ResponseHelper.PERMISSION_WSCQX);
            }
            if (string.IsNullOrEmpty(input.Ids))
            {
                return ResponseHelper.MessageResult(ResponseHelper.PARAMETER_CSCW);
            }
            int result = await _userService.DeleteAsync(input.Ids);
            return ResponseHelper.DeleteResult(result);
        }

        [HttpPost]
        [OpLog]
        public async Task<ResponseResult> ModifyEnabled([FromBody] MoifyStateInput input)
        {
            var r = SysPower(SysMenuConstant.MENU_SYS_USER, SysMenuConstant.FUN_UPDATE, UserInfo.ID.ToString(), false);
            if (!r)
            {
                return ResponseHelper.MessageResult(ResponseHelper.PERMISSION_WSCQX);
            }
            if (string.IsNullOrEmpty(input.Id.ToString()))
            {
                return ResponseHelper.MessageResult(ResponseHelper.PARAMETER_CSCW);
            }
            int result = await _userService.UpdateEnable(input.Id, input.State);
            return ResponseHelper.OperateResult(result);
        }

        [HttpPost]
        [OpLog]
        public async Task<ResponseResult> ModifyPassWord([FromBody]UserModifyPwdInput input )
        {
            //string oripwd, string pwd,string againpwd
            int result ;
            if (string.IsNullOrEmpty(input.NewPwd) || string.IsNullOrEmpty(input.AgainPwd))
            {
                return ResponseHelper.MessageResult(ResponseHelper.PARAMETER_MYQRMABNWK);
            }
            if (!string.Equals(input.NewPwd, input.AgainPwd,StringComparison.CurrentCultureIgnoreCase))
            {
                return ResponseHelper.MessageResult(ResponseHelper.PARAMETER_MBBYZ);
            }
            var usermodel =await _userService.GetByIdAsync(UserInfo.ID);
            if (usermodel != null && usermodel.UserPwd != MD5Encryption.Encrypt(input.OriginalPwd))
            {
                return ResponseHelper.MessageResult(ResponseHelper.PARAMETER_YMMCW);
            }
            result =await _userService.UpdatePwd( UserInfo.ID, MD5Encryption.Encrypt(input.NewPwd));

            return ResponseHelper.OperateResult(result);
        }

        [HttpPost]
        public async Task<ResponseResult> ExistsUserName()
        {
            var jsondata = RequestHelper.GetInputStream(Request.Body);

            var userName = jsondata["userName"].GetValue<string>();
            var id = jsondata["id"].GetValue<long>();

            if (string.Equals("admin", userName, StringComparison.InvariantCultureIgnoreCase))
            {
                return ResponseHelper.MessageResult(ResponseHelper.OPERATE_YHMYBZY);
            }
            var expable = Expressionable.Create<SysUserEntity>();

            expable.And(a => a.UserName == userName);
            expable.AndIF(id > 0, a => a.Id != id);
            var exp = expable.ToExpression();
            var userlist = await _userService.List(exp, null);

            if (userlist.Count > 0)
            {
                return ResponseHelper.MessageResult(ResponseHelper.OPERATE_YHMYBZY);
            }
            else
            {
                return ResponseHelper.MessageResult(ResponseHelper.OPERATE_YHMKY);
            }
        }
        [HttpGet]
        public async Task<FileResult> GetProfilePicture()
        {
            var output =await _userService.GetByIdAsync(UserInfo.ID);
            if (string.IsNullOrEmpty(output?.Avatar))
            {
                return GetDefaultProfilePictureInternal();
            }
            return File(output.Avatar, "image/jpeg");
        }

        [HttpPost]
        [OpLog]
        public async Task<ResponseResult> ModifyUserAvatar([FromBody]UserAvatarInput input)
        {
            if (string.IsNullOrEmpty(input.Url))
            {
                return ResponseHelper.MessageResult(ResponseHelper.PARAMETER_TXDZBWK);
            }
            int result = await _userService.UpdateAvater(UserInfo.ID, input.Url);
            return ResponseHelper.OperateResult(result);
           
        }
        [HttpPost]
        [OpLog]
        public async Task<ResponseResult> ResetPwd([FromBody]UserRestPwdInput input)
        {
            var r = SysPower(new List<string>() { SysMenuConstant.MENU_SYS_USER}, SysMenuConstant.FUN_RESETPWD, UserInfo.ID.ToString(), false);

            if (!r)
            {
                return ResponseHelper.MessageResult(ResponseHelper.PERMISSION_QXZU);
            }

            var restpwd =await _configurationService.GetValueByCode("RESTPWD");
         
            int result =await _userService.UpdatePwd(input.Uid, MD5Encryption.Encrypt(restpwd));
            return ResponseHelper.OperateResult(result);
           
        }

        [HttpPost]
        public async Task<ResponseResult> Audit([FromBody]UserAuditInput input)
        {
            var r = SysPower(SysMenuConstant.MENU_SYS_USER, SysMenuConstant.FUN_AUDIT, UserInfo.ID.ToString(), false);
            if (!r)
            {
                return ResponseHelper.MessageResult(ResponseHelper.PERMISSION_QXZU);
            }
            if (string.IsNullOrEmpty(input.Uid))
            {
                return ResponseHelper.MessageResult(ResponseHelper.PARAMETER_CSCW);
            }

            List<SysUserRoleEntity> listrole = new List<SysUserRoleEntity>();
            var uids = input.Uid.GetStringArrayNoNull();
            var roles = input.Roles.GetStringArrayNoNull();
            for (int i = 0; i < uids.Length; i++)
            {
                for (int j = 0; j < roles.Length; j++)
                {
                    listrole.Add(new SysUserRoleEntity { UserId = uids[i].ParseToLong(), RoleCode = roles[j]});
                }
                
            }
            int result=await _userService.InsertAuditUser(listrole,null);
            if (result > 0)
            {
                await _userService.AuditUser(input.Uid);
            }
            return ResponseHelper.OperateResult(result);
           
        }

        [HttpGet]
        public async Task<List<NoticeOutput>> MseeageList()
        {
            //return new ResponseDataResult
            //{
            //    code = 0,
            //    message = "成功",
            //    data = await GetUserMseeage()
            //};

            List<NoticeOutput> list = new List<NoticeOutput>();

            NoticeOutput noticeOutput = new NoticeOutput();

            noticeOutput.Id = 1;
            noticeOutput.Title = "通知";

            var notice0 = await GetUserMseeage(0);
            List<NoticeChildren> notice0list = new List<NoticeChildren>();
            foreach (var item in notice0)
            {
                notice0list.Add(new NoticeChildren {
                    Id =item.Id,
                    Avatar = "/images/msg.png",
                    Context = "",
                    Form = item.PublicUserName,
                    Time = item.PublicTime?.ToString("yy-MM-dd"),
                    Title  =item.Title
                });
            }
            noticeOutput.Children = notice0list;
            list.Add(noticeOutput);
           
            NoticeOutput noticeOutput2 = new NoticeOutput();

            noticeOutput2.Id = 2;
            noticeOutput2.Title = "公告";

            var notice1 = await GetUserMseeage(1);
            List<NoticeChildren> notice1list = new List<NoticeChildren>();
            foreach (var item in notice1)
            {
                notice1list.Add(new NoticeChildren
                {
                    Id = item.Id,
                    Avatar = "/images/msg.png",
                    Context ="",
                    Form = item.PublicUserName,
                    Time = item.PublicTime?.ToString("yy-MM-dd"),
                    Title = item.Title
                });
            }
            noticeOutput2.Children = notice1list;
            list.Add(noticeOutput2);

            return list;

        }
      
        #endregion

        #region 私有方法
        protected FileResult GetDefaultProfilePictureInternal()
        {
            return File(CoreHttpContext.MapPath("/images/head.png"), "image/jpeg");
        }
        /// <summary>
        /// 获取消息
        /// </summary>
        /// <returns></returns>
        private async  Task<List<dynamic>> GetUserMseeage(int noticType)
        {
            var expable = Expressionable.Create<SysNoticeEntity, SysNoticeUserEntity>();
            expable.And((a, b) => a.NoticType == noticType);
            expable.And((a, b) => b.UserId == UserInfo.ID && b.ReadStatus ==0 );
            //expable.AndIF(!string.IsNullOrEmpty(content), (a, b) => a.Content.Contains(content));
            var exp = expable.ToExpression();
            Expression<Func<SysNoticeEntity, SysNoticeUserEntity, object>> expressionOrder;
            expressionOrder = (a, b) => new { a.CreateDate };
            var result = await _noticeService.NoticeList(exp, 100, expressionOrder,(a,b)=>new { Id =a.Id, PublicUserName = a.PublicUserName, Title = a.Title, PublicTime =a.PublicTime });
            return result;
        }
        #endregion
    }
}